﻿// Copyright (c) 2012 - 2020 Jared Zheng <jaredz at outlook dot com>
// Buddha Framework is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//          http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
//
// Create : 2012-12-01 version 0.1 Jared Zheng <jaredz at outlook dot com>
// Update : 2018-12-05 version 3.1.5 Jared Zheng <jaredz at outlook dot com>

#include "stdafx.h"
#include "ServerConsole.h"
#include "ServiceHandler.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// CServiceHandler
CServiceHandler::CServiceHandler(void)
: m_uServiceOnline(0)
, m_uServiceTotal(0)
, m_uServiceLoad(0)
, m_uMasterId(0)
, m_uRoutineIds(0)
{
}

CServiceHandler::~CServiceHandler(void)
{
}

void CServiceHandler::OnLive(bool bStart)
{
    CStringFix strTemp = GetName();
    if (bStart)
    {
        strTemp += TF("Start---Service Routines:");
    }
    else
    {
        strTemp += TF("Stop");

        m_uServiceOnline = 0;
        m_uServiceTotal  = 0;
        m_uServiceLoad   = 0;
        m_uMasterId      = 0;
        m_uRoutineIds    = 0;
    }
    LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);
}

void CServiceHandler::OnLink(Int nServerIndex, uintptr_t utData)
{
    CStringFix strTemp = GetName();
    if (nServerIndex == PAKT_MASTER)
    {
        strTemp += TF("TCP Int-Connect Master=");

        CNetAddr* pAddr = (reinterpret_cast<CNetAddr*>(utData));

        CStrAddr strAddr;
        GServerConsoleInst->m_Config.GetServerAddr(CServerConfig::CFG_LOAD_MASTER, CServerConfig::CFG_LOAD_NONE, strAddr);
        strTemp.AppendFormat(TF("[%s]:%d"), *strAddr.strIp, strAddr.usPort);

        GServerConsoleInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pAddr, false);
        strTemp.AppendFormat(TF("([%s]:%d)"), *strAddr.strIp, strAddr.usPort);
    }
    else if (nServerIndex == PAKT_MASTERDB)
    {
        strTemp += TF("TCP Int-Connect MasterDB=");
        if (utData != 0)
        {
            CNetAddr* pAddr = (reinterpret_cast<CNetAddr*>(utData));

            CStrAddr strAddr;
            GServerConsoleInst->m_Config.GetServerAddr(CServerConfig::CFG_LOAD_MASTERDB, CServerConfig::CFG_LOAD_NONE, strAddr);
            strTemp.AppendFormat(TF("[%s]:%d"), *strAddr.strIp, strAddr.usPort);

            GServerConsoleInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pAddr, false);
            strTemp.AppendFormat(TF("([%s]:%d)"), *strAddr.strIp, strAddr.usPort);
        }
        else
        {
            strTemp += TF("---");
        }
    }
    else if (nServerIndex == PAKT_SERVICE)
    {
        CString strRId = reinterpret_cast<PCXStr>(utData);
        ULLong ullHash = CHash::Hash64(*strRId);

        strTemp.AppendFormat(TF("Linked RID=%llX"), ullHash);
    }
    else if (nServerIndex == PAKT_SERVICE_MASTER)
    {
        CString strRId = reinterpret_cast<PCXStr>(utData);

        ULLong ullHash = FALSE;
        for (size_t i = 0; i < strRId.Length(); ++i)
        {
            if (strRId.IsXDigitChar(i))
            {
                ullHash = TRUE;
                break;
            }
        }
        ullHash = strRId.ToULLong((ullHash == TRUE) ? RADIXT_HEX : RADIXT_DEC);
        strTemp.AppendFormat(TF("Linked RID=%llX"), ullHash);
    }
    LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);
}

void CServiceHandler::OnUpdate(Int nLinkAck, uintptr_t utData)
{
    CStringFix strTemp;
    if (nLinkAck == 0)
    {
        strTemp.AppendFormat(TF("Online RID=%llX Okay"), utData);
    }
    else
    {
        strTemp.AppendFormat(TF("Linked RID=%llX Failed ERRID=%d"), utData, nLinkAck);
    }
    LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);
}

void CServiceHandler::OnSync(Int nServerIndex, uintptr_t utData)
{
    if (nServerIndex == PAKT_SERVICE)
    {
        PSERVER_STATUS pStatus = reinterpret_cast<PSERVER_STATUS>(utData);
        m_uServiceTotal   = pStatus->uTotal;
        m_uServiceOnline  = pStatus->uOnline;
        m_uServiceLoad    = pStatus->usLoad;
        m_uMasterId       = pStatus->usIncr;
    }
    else if (nServerIndex == PAKT_MASTER)
    {
        m_uMasterId       = (UInt)utData;
        if (utData == 0)
        {
            CStringFix strTemp;
            strTemp.Format(TF("Disconnect Master Server, All Online RID Offlined"));
            LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);
        }
    }
    else
    {
        m_uRoutineIds     = (UInt)utData;

        CStringFix strTemp;
        strTemp.Format(TF("Server all RID count=%d"), m_uRoutineIds);
        LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);
    }
}

void CServiceHandler::OnSync(Int, CStream&)
{
}

void CServiceHandler::OnUnlink(Int nServerIndex, uintptr_t utData)
{
    CStringFix strTemp;
    if (nServerIndex == PAKT_MASTER)
    {
        LOG_INFO(GServerConsoleInst->m_FileLog, TF("Service:TCP Int-Connect Master Closed"));
    }
    else if (nServerIndex == PAKT_MASTERDB)
    {
        LOG_INFO(GServerConsoleInst->m_FileLog, TF("Service:TCP Int-Connect MasterDB Closed"));
    }
}

void CServiceHandler::UpdateServerInfo(void)
{
    CStringFix strTemp;
    strTemp.Format(TF("[%u/%u, Load=%d%%]Connected-Master Id:%d"),
                   m_uServiceOnline, m_uServiceTotal, m_uServiceLoad, m_uMasterId);
    LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);
}

PCXStr CServiceHandler::GetName(void)
{
    return TF("Service:");
}




